package com.tqfframe.studydemo.myDubboRpc.core.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.Timeout;
import io.netty.util.Timer;
import io.netty.util.TimerTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 *  context.writeAndFlush("传输内容") 方法是客户端和服务端接收的关键，在channelRead方法中接收传输内容。
 *
 * Created by Tang-QiFeng on 2022/2/18
 */
public class ClinetHandler  extends ChannelInboundHandlerAdapter implements Callable{
    private Logger logger=LoggerFactory.getLogger(this.getClass());

    private ChannelHandlerContext context;
   //返回的内容
    private Object result;
    //传参
    private String para;

    //和服务端服务第一次连接后执行
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("我来自客户端的链接，我与服务端建立连接");
        context = ctx;
        ctx.fireChannelActive();
    }

    //服务端服务断开连接后执行
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("我与服务端链接断开，服务端宕机了。。。我需要进行重连");
        ctx.fireChannelInactive();
    }


    /**
     * 接收服务端发送过来的数据，并且使用notify()解除阻塞状态
     *   ！！！所以必须要有服务端数据返回，否则会一直阻塞。
     * @param ctx
     * @param msg
     */
    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) {
        logger.info("接收到来自服务端返回的接口内容..."+msg);
        result = msg;
        notify();
    }

    /**
     * 使用阻塞方法，把参数推送到服务端，等待服务端返回数据,所以必须要有返回，否则会一直阻塞
     *  notify方法在上面channelRead方法中。
     * @return
     * @throws Exception
     */
    @Override
    public synchronized Object call() throws Exception {
        context.writeAndFlush(para);
        wait();
        return result;
    }


    public void setPara(String para) {
        this.para = para;
    }

}
